home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
gdb
/
gdb_18s.zoo
/
atarist.c
next >
Wrap
C/C++ Source or Header
|
1992-04-27
|
19KB
|
744 lines
/* glue funs and things that substitute for eunuchs funs */
#include <stdio.h>
#include <osbind.h>
#include <setjmp.h>
#include <ctype.h>
#include <signal.h>
#include <regexp.h>
#include "st-traps.h"
#include "wait.h"
#include "m-atari.h"
#include "defs.h"
#include "symtab.h"
struct tpa /* what the hell does 'tpa' stand for anyway?*/
{
struct tpa * self; /* self or parent??? */
long * memtop; /* top of mem this tpa */
long * text_base;
long text_size;
long * data_base;
long data_size;
long * bss_base;
long bss_size;
/* there's more crap here, but I think it doesn't matter */
};
struct tpa * child_tpa;
int atari_debug = 0;
#if 0
long _stksize = 128 *1024L; /* might as well put this here */
#else
long _initial_stack = 512 *1024L;
#endif
#define CHILD_PID_KLUDGE 1
int child_is_running = 0;
long old_vectors[10];
long old_trap_0_vector;
long old_trap_f_vector;
long set_exception_vector();
#if 1 /* def JRDLIB */
/* for st-infru.c */
char * sys_siglist[] =
{
"null",
"alarm",
"bus error",
"address error",
"illegal instruction",
"div by zero",
"CHK instruction",
"TRAPV instruction",
"priv violation",
"T-bit trap",
"Breakpoint",
"interrupt",
"quit"
};
#endif
/* for st-inflo.c... */
static volatile jmp_buf exec_context, pre_pexec_context;
static char kludge_cmd[MAXPATHLEN];
static char * kludge_argstring;
static char * kludge_env;
static volatile long kludge_pexec_result;
static char pexec_stack[256];
st_execle_kludge(args, env)
/* BOGON ALERT!!! the caller has 'args' declared as a char **, but
that's clearly bogus, given the way it's constructed. Look in
infcmd.c. It's really a char *. I hate C... */
char * args;
char ** env;
{
int i, envlen;
char cmdname[80], argstring[258];
char * p, * q;
static char run_already = 0;
if(run_already)
return -9999;
else
run_already = 1;
/* zzz */
/*
fprintf_filtered(stderr, "Execle_kludge:\n");
fprintf_filtered(stderr, "\t'%s'\n", args);
fprintf_filtered(stderr, "\tenv:\n");
for (i = 0 ; env[i] ; i++)
fprintf_filtered(stderr, "\t\t'%s'\n", env[i]);
*/
/* construct the environment string */
envlen = 0;
for (i = 0; env[i]; i++)
envlen += strlen(env[i]) + 1;
envlen += 1;
p = kludge_env = xmalloc(envlen);
for (i = 0; env[i]; i++)
{
/*
* NOTE: in main.c, we converted the PATH environment variable into
* POSIX form. Here, we convert back into gulam form. Note that the
* new variable will be shorter than the old, so space is not a
* problem.
*/
if (!strncmp (env[i], "PATH=", 5))
{
strncpy (p, env[i], 5);
p += 5;
for (q = env[i] + 5; *q; q++)
{
if (!strncmp (q, "/dev/", 5) && q[5])
{
*p++ = q[5];
*p++ = ':';
q += 5;
}
else if (*q == ':')
*p++ = ',';
else if (*q == '/')
*p++ = '\\';
else
*p++ = *q;
}
}
else
for (q = env[i]; *q; q++)
*p++ = *q;
*p++ = '\0';
}
*p = '\0';
/* the obligatory cmd line parsing */
cmdname[0] = '\0';
/* cmd string has 'exec' in front of it. */
for (p = args + 4 ; (*p && isspace(*p)) ; p++)
;
for (q = &cmdname[0] ; (*p && !isspace(*p)) ; )
*q++ = *p++;
*q = '\0';
for ( ; (*p && isspace(*p)) ; p++)
;
argstring[1] = '\0';
for (q = &argstring[1] ; (*p) ; )
*q++ = *p++;
*q = '\0';
argstring[0] = strlen(&argstring[1]);
unx2dos(&cmdname[0], kludge_cmd);
exception_number = 0;
old_ipl_2_vector =
set_exception_vector(26, ipl_2_vector); /* our startup trap */
if (!setjmp(exec_context))
{
/* ok, we're either coming thru here the first time, before
the spawn, or after taking the kludge return. child_running
tells us which one */
if (child_is_running)
{
/* something's really fucked here. We're not supposed to
be able to come thru here except when we're starting
things */
fprintf_filtered(stderr, "Internal error!!! child already running?\n");
return(0);
}
else
{
/* set the running flag, arrange to return to that setjmp above,
and start the child. */
child_is_running = 1;
setup_fake_debugger_context(exec_context);
/* if we could be sure of the stack, we'd say...
Pexec(PE_LOADGO, cmdname, argstring, env);
but we can't. instead... */
/* fprintf_filtered(stderr, "Pexec('%s', '%s')\n",
&cmdname[0], &argstring[1]);
*/
/* kludge_cmd = &cmdname[0]; */
kludge_argstring = &argstring[0];
if(setjmp(pre_pexec_context))
{
free(kludge_env);
/* we're returning after the child exits. the stack
is all fucked here, so reset to top level */
child_is_running = 0;
fprintf(stderr, "Program exitted with status %ld\n",
kludge_pexec_result);
exception_number = SIGTRACE; /* not really... */
inferior_died(); /* I think this is safe here */
return_to_top_level(); /* clean up stack and restart */
return(CHILD_PID_KLUDGE); /* just in case ... */
}
/* must make sp point to someplace nonvolatile, as we're going to do
a bunch of context switching before we actually 'exit' from this
pexec. */
#ifndef OLDTOS
/* default - TOS 1.4 or better required
use Pexec 3+6 */
asm volatile("\
movel #_pexec_stack+252,sp
movel _kludge_env,sp@-
movel _kludge_argstring,sp@-
movel #_kludge_cmd,sp@-
movew #3,sp@-
movew #0x4B,sp@-
trap #1
addw #16,sp
clrl sp@-
movel d0, sp@-
clrl sp@-
movew #6, sp@-
movew #0x4B,sp@-
trap #1
movel d0,_kludge_pexec_result");
#else
/* pre tos 1.4 -- get a life man
use Pexec 0 */
asm volatile("\
movel #_pexec_stack+252,sp
movel _kludge_env,sp@-
movel _kludge_argstring,sp@-
movel #_kludge_cmd,sp@-
movew #0,sp@-
movew #0x4B,sp@-
trap #1
movel d0,_kludge_pexec_result");
#endif
#if 0
free(kludge_env);
/* we're returning after the child exits. the stack
is all fucked here, so reset to top level */
child_is_running = 0;
exception_number = SIGTRACE; /* not really... */
inferior_died(); /* I think this is safe here */
return_to_top_level(); /* clean up stack and restart */
#else
longjmp(pre_pexec_context, 1);
#endif
}
}
else
{
/* we have just spawned the child, and are returning from
preparing to execute him. return
the fake pid so we can continue initialiation */
set_exception_vector(26, old_ipl_2_vector);
{
long * child_sp = (long *)child_context.registers[15];
child_tpa = (struct tpa * )child_sp[1];
/* fprintf_filtered(stderr, "child tpa at %X\n", child_tpa); */
relocate_apropriate_symbols(child_tpa->text_base);
exception_number = 0;
}
}
return(CHILD_PID_KLUDGE);
}
#if 1 /* def JRDLIB */
/* called various places */
int kill(fake_pid, signal)
int fake_pid;
int signal;
{
extern void request_quit();
if (fake_pid == CHILD_PID_KLUDGE)
{
/* if the child is running, then TOS thinks we're it, so just exit */
if (child_is_running)
Pterm0();
/* doesn't return... */
else
fprintf_filtered(stderr, "Internal error: attempt to kill when child not running\n");
}
else if (fake_pid == getpid ())
{
if (signal == SIGINT)
request_quit();
}
else
fprintf_filtered(stderr, "You can't kill pid %d, bozo!\n", fake_pid);
return(-1);
}
#endif
/* called from various places, mostly st-infru.c */
int st_wait_kludge(w)
WAITTYPE * w;
{
/* fprintf_filtered(stderr, "st-wait-kludge: running %d exc %d\n",
child_is_running, exception_number); */
if (child_is_running)
{
WSETSTOP(*w, exception_number);
return(CHILD_PID_KLUDGE);
}
else
{
WSETEXIT(*w, 0);
return(-1);
}
}
static char *regcomp_error = 0;
static regexp *compiled_regex = 0;
/* Remember the last error message from regcomp */
void regerror(message)
char *message;
{
regcomp_error = message;
}
char *re_c